home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 90 / CD Actual 90.iso / Software3D / PovLab / povlab / PLUGINS / HELIX.ZIP / HELIX.C next >
Encoding:
C/C++ Source or Header  |  1996-05-04  |  16.8 KB  |  599 lines

  1. /*
  2.     helix.c
  3.  
  4.     COMPILER:
  5.         Borland C++ 3.1
  6.         Watcom 10.x
  7.  
  8.     DESCRIPTION:
  9.         This file is a plugin for POVLAB 3.2 onwards.
  10.         This file creates a helix of objects with the ability
  11.             to change various parameters.
  12.  
  13.     CONTENTS:
  14.         1 to 6 heli of objects.
  15.         Clockwise or anticlockwise helix creation.
  16.         Y axis rotation offset for the entire helix.
  17.         Variable length Helix.
  18.         Static or changing helix radius over length.
  19.         Variable number of objects per revolution of helix.
  20.         Scaling of objects in helix from unity in X, Y and Z directions.
  21.         Rotation of objects within the helix in X, Y and Z directions.
  22.         The ability to face all objects towards the center of the helix.
  23.  
  24.     NOTE:
  25.         All of the above can be performed in _any_ combination.
  26.         This file was written with the TAB key defined as 3 spaces.
  27.         The commandline argument created by POVLAB using this plugin is VERY
  28.           long, in some cases you may run into truncation problems.  Hopefully
  29.           this risk will be fixed at sometime in the future.
  30.  
  31.     CopyLeft Robert Hodkinson (r.j.hodkinson@bradford.ac.uk).
  32.         Started: early March 1996.  Current: early  April 1996.
  33. */
  34.  
  35.  
  36. #if __WATCOMC__
  37.   #include <i86.h>
  38. #else
  39.   #include <dos.h>
  40. #endif
  41.  
  42. #include <io.h>
  43. #include <math.h>
  44. #include <stdio.h>
  45. #include <conio.h>
  46. #include <string.h>
  47. #include <stdlib.h>
  48.  
  49. /* global declarations */
  50. #define RAD            (180/M_PI)    // number of degrees in a radian
  51.  
  52.  
  53. /* declare prototypes */
  54. int    OutDataInterface(void);
  55. void     MakeHelix(double);
  56. void     ExtractParameters(char *argv[]);
  57. void   CalculateHelix(void);
  58. void   CalculateSetValues(void);
  59.  
  60. double CalcXcoord(double, double);
  61. double CalcYcoord(double);
  62. double CalcZcoord(double, double);
  63.  
  64. double CalcXrotation(void);
  65. double CalcYrotation(double);
  66. double CalcZrotation(void);
  67.  
  68.  
  69. /* global variables filled from argv[] (in this order) */
  70. double HELIXRADSTART;    // start radius of the helix
  71. double HELIXRADEND;        // end   radius of the helix
  72.  
  73. double HELIXLENGTH;        // length of helix
  74.  
  75. int    OBJECTSPERREV;    // number of spheres per 360 degrees revolution
  76. double LENGTHPERREV;        // distance covered per helix revolution
  77.  
  78. double HELIXOFFSETX;        // translation offset for the helix
  79. double HELIXOFFSETY;        // translation offset for the helix
  80. double HELIXOFFSETZ;        // translation offset for the helix
  81.  
  82. double HELIXROTATEY;        // rotation of the entire helix on the Y axis
  83.  
  84. double OBJECTSCALEX;        // object scale on the X axis
  85. double OBJECTSCALEY;    // object scale on the Y axis
  86. double OBJECTSCALEZ;    // object scale on the Z axis
  87.  
  88. int    ROTATETOFACE;        // if enabled, will allow mass rotation objects
  89. double OBJECTROTATEX;    // object rotate on the X axis
  90. double OBJECTROTATEY;    // object rotate on the Y axis
  91. double OBJECTROTATEZ;    // object rotate on the Z axis
  92.  
  93. int    STARTOBJNO;        // which object number to start at
  94.  
  95. int    NOOFHELIX;            // number of helix in cylinder
  96.  
  97. int    OBJECTTYPE;        // type of object to use in the helix
  98.  
  99. int    HELIXCLOCKWISE;    // is the helix clockwise or anticlock
  100.  
  101.  
  102. /* global variables caclulated before making helix */
  103. FILE *Helix;                // file stream to be used by helix1.c
  104.  
  105. double RadiansPerObject;    // rotation per object in helix (radians)
  106.  
  107. double HelixRadiusStart;            // acutal minimum raidus of helix
  108. double HelixRadiusIncPerObject;    // radius incramented/decramented per sphere in helix
  109.  
  110. double LengthPerObject;        // length incramented for each degree incrament
  111.  
  112. double HelixRotationY;        // helix rotation offset
  113.  
  114. int    Objno;                    // incramental object numbering
  115.  
  116.  
  117. /*    main program */
  118.  
  119. /*
  120.     function - root of main loop to create helix
  121. */
  122. void main (int argc,char *argv[])
  123. {
  124.     union REGS regs;
  125.     int        i;
  126.  
  127.     // do we have arguments and do they start correctly?
  128.     if(argc>1)
  129.     {
  130.         if(strcmp(strupr(argv[1]),"/ASK")==NULL)
  131.         {
  132.             // create PLG file
  133.             OutDataInterface();
  134.             exit(0);
  135.         }
  136.     }
  137.     else
  138.     {
  139.         exit(0);
  140.     }
  141.  
  142.     // test stuff for argument length, KEEP!!
  143. /*    printf("argv's:");
  144.  
  145.     for(i=0;i<=20;i++)
  146.         printf("%s:", argv[ i]);
  147.  
  148.     printf("end\n");
  149.     printf("paused....\n");
  150.     getch();
  151. */
  152.     // clear screen
  153.     #if __WATCOMC__
  154.         regs.w.ax=3;
  155.     #else
  156.         regs.x.ax=3;
  157.     #endif
  158.     int86(0x10,®s,®s); // Textmode with int 10H
  159.  
  160.     // copyleft and all that useless junk
  161.     puts("");
  162.     printf("Helix maker (Helix.exe), (L) Robert Hodkinson, 1996.\n");
  163.     printf("External process for POVLAB - \n");
  164.     printf("To Generate all sorts of wierd helix.\n");
  165.     puts("");
  166.  
  167.     // extract parameters sent by POVLAB
  168.     ExtractParameters(argv);
  169.  
  170.     // create .inc file to store all the stuff in.
  171.     Helix = fopen("Helix.inc","w+t");
  172.  
  173.     // calculate all set values for use
  174.     CalculateSetValues();
  175.  
  176.     // calculate helix ALL GO!
  177.     CalculateHelix();
  178. }
  179.  
  180.  
  181.  
  182.  
  183. /*
  184.     function - to create the plg file for povlab to use
  185. */
  186. int OutDataInterface()
  187. {
  188.     // open the plg file
  189.     if(!(Helix = fopen("Helix.plg","wt")))
  190.         return 0;
  191.  
  192.     // fill the plg file
  193.     fprintf(Helix, "TITLE: The_wierd_and_wonderful_Helix_maker_(Helix)_v1.0\n");
  194.     fprintf(Helix, "COPYRIGHT: CopyLeft_Robert_Hodkinson_1996_-_All_rights_reserved.\n");
  195.     fprintf(Helix, "WINDOW:   530 290 \n");
  196.  
  197.     // start of first column of options
  198.     fprintf(Helix, "TEXTZONE:  90  50 Helix_radius_start  5 Radius_of_Helix_to_create \n");
  199.     fprintf(Helix, "TEXTZONE:  90  70 Helix_radius_end    5 Radius_of_Helix_to_create \n");
  200.  
  201.     fprintf(Helix, "TEXTZONE:  90 100 Helix_length       10 Length of_Helix_to_create \n");
  202.  
  203.     fprintf(Helix, "TEXTZONE:  90 130 Objects_per_rev    20 Number_of_Helix_per_revolution   \n");
  204.     fprintf(Helix, "TEXTZONE:  90 150 Length_per_rev     10 Distance_covered_pre_revolution  \n");
  205.  
  206.     fprintf(Helix, "TEXTZONE:  90 180 Helix_offset_X      0 Helix_translation_in_the_X_axis  \n");
  207.     fprintf(Helix, "TEXTZONE:  90 200 Helix_offset_Y      0 Helix_translation_in_the_Y_axis  \n");
  208.     fprintf(Helix, "TEXTZONE:  90 220 Helix_offset_Z      0 Helix_translation_in_the_Z_axis  \n");
  209.  
  210.     fprintf(Helix, "TEXTZONE:  90 250 Helix_rotate_Y      0 Helix_rotation_in_the_Y_axis     \n");
  211.  
  212.     // start of second column of options
  213.     fprintf(Helix, "TEXTZONE: 280  50 Object_No_Start   100 First_Object_Number_to_be_used   \n");
  214.  
  215.     fprintf(Helix, "TEXTZONE: 280  80 Object_scale_X      1 Scale_object_in_the_X_dimension  \n");
  216.     fprintf(Helix, "TEXTZONE: 280 100 Object_scale_Y      1 Scale_object_in_the_Y_dimension  \n");
  217.     fprintf(Helix, "TEXTZONE: 280 120 Object_scale_Z      1 Scale_object_in_the_Z_dimension  \n");
  218.  
  219.     fprintf(Helix, "TEXTZONE: 280 150 Object_rotate_X     0 Rotate_object_in_the_X_dimension \n");
  220.     fprintf(Helix, "TEXTZONE: 280 170 Object_rotate_Y     0 Rotate_object_in_the_Y_dimension \n");
  221.     fprintf(Helix, "TEXTZONE: 280 190 Object_rotate_Z     0 Rotate_object_in_the_Z_dimension \n");
  222.  
  223.     fprintf(Helix, "RADIO:    280 220 Object_Sphere       1 Create_a_Helix_using_spheres   1 \n");
  224.     fprintf(Helix, "RADIO:    280 240 Object_Cube         0 Create_a_Helix_using_cubes     1 \n");
  225.  
  226.     // start of thrid row of options
  227.     fprintf(Helix, "RADIO:    390  50 Single_Helix        1 Create_a_single_Helix_shape    2 \n");
  228.     fprintf(Helix, "RADIO:    390  70 Double_Helix        0 Create_a_double_Helix_shape    2 \n");
  229.     fprintf(Helix, "RADIO:    390  90 Triple_Helix        0 Create_a_triple_Helix_shape    2 \n");
  230.     fprintf(Helix, "RADIO:    390 110 Quadruple_Helix     0 Create_a_quadruple_Helix_shape 2 \n");
  231.     fprintf(Helix, "RADIO:    390 130 Quintple_Helix      0 Create_a_quintple_Helix_shape  2 \n");
  232.     fprintf(Helix, "RADIO:    390 150 Hextaple_Helix      0 Create_a_hextaple_Helix_shape  2 \n");
  233.  
  234.     fprintf(Helix, "RADIO:    390 180 Clockwise_Helix     1 Create_a_clockwise_Helix       3 \n");
  235.     fprintf(Helix, "RADIO:    390 200 Anticlock_Helix     0 Create_an_anticlockwise_Helix  3 \n");
  236.  
  237.     fprintf(Helix, "CASE:     390 230 Face_Object_inwards 0 If_not_enabled,_objects_will_all_face_the_same_way \n");
  238.  
  239.     fprintf(Helix, "MESSAGE: The_Helix_cylinder_is_created_in_the_X_&_Y_axis_from_<0,0,0> \n");
  240.     fprintf(Helix, "END:\n");
  241.  
  242.     fclose(Helix);
  243.  
  244.     return 1;
  245. }
  246.  
  247.  
  248.  
  249. /*
  250.     function - to extract the needed parameters from POVLAB into helix1.c
  251. */
  252. void ExtractParameters(char *argv[])
  253. {
  254.     int i;
  255.  
  256.     i = 1;
  257.  
  258.     HELIXRADSTART  = atof(argv[ i]);
  259.     i++;
  260.     HELIXRADEND       = atof(argv[ i]);
  261.     i++;
  262.     HELIXLENGTH    = atof(argv[ i]);
  263.     i++;
  264.     OBJECTSPERREV  = atof(argv[ i]);
  265.     i++;
  266.     LENGTHPERREV   = atof(argv[ i]);
  267.     i++;
  268.     HELIXOFFSETX   = atof(argv[ i]);
  269.     i++;
  270.     HELIXOFFSETY   = atof(argv[ i]);
  271.     i++;
  272.     HELIXOFFSETZ   = atof(argv[ i]);
  273.     i++;
  274.     HELIXROTATEY   = atof(argv[ i]);
  275.     i++;
  276.  
  277.     // end of first column
  278.     STARTOBJNO     = atof(argv[ i]);
  279.     i++;
  280.     OBJECTSCALEX   = atof(argv[ i]);
  281.     i++;
  282.     OBJECTSCALEY   = atof(argv[ i]);
  283.     i++;
  284.     OBJECTSCALEZ   = atof(argv[ i]);
  285.     i++;
  286.  
  287.     OBJECTROTATEX  = atof(argv[ i]);
  288.     i++;
  289.     OBJECTROTATEY  = atof(argv[ i]);
  290.     i++;
  291.     OBJECTROTATEZ  = atof(argv[ i]);
  292.     i++;
  293.     OBJECTTYPE     = atof(argv[ i]) + 1; // 1 = sphere, 2 = cube
  294.     i++;
  295.  
  296.     // end of second column
  297.     NOOFHELIX      = atof(argv[ i]);
  298.     i++;
  299.     HELIXCLOCKWISE = atof(argv[ i]);
  300.     i++;
  301.     ROTATETOFACE   = atof(argv[ i]);
  302.  
  303.  
  304.     // give a status for the user to jaw wag at (not!)
  305.     // first column of options
  306.     printf("Helix Radius Start       :%f:\n", HELIXRADSTART);
  307.     printf("Helix Radius End         :%f:\n", HELIXRADEND);
  308.     printf("Helix Length             :%f:\n", HELIXLENGTH);
  309.     printf("Objects per revolution   :%d:\n", OBJECTSPERREV);
  310.     printf("Length  per revolution   :%f:\n", LENGTHPERREV);
  311.     printf("Helix translation X      :%f:\n", HELIXOFFSETX);
  312.     printf("Helix translation Y      :%f:\n", HELIXOFFSETY);
  313.     printf("Helix translation Z      :%f:\n", HELIXOFFSETZ);
  314.     printf("Helix rotation Y         :%f:\n", HELIXOFFSETZ);
  315.  
  316.     // second column of options
  317.     printf("Object type              :%d:\n", OBJECTTYPE);
  318.     printf("Object scale X           :%f:\n", OBJECTSCALEX);
  319.     printf("Object scale Y           :%f:\n", OBJECTSCALEY);
  320.     printf("Object scale Z           :%f:\n", OBJECTSCALEZ);
  321.     printf("Object rotation X        :%f:\n", OBJECTROTATEX);
  322.     printf("Object rotation Y        :%f:\n", OBJECTROTATEY);
  323.     printf("Object rotation Z        :%f:\n", OBJECTROTATEZ);
  324.     printf("Object start number      :%d:\n", STARTOBJNO);
  325.  
  326.     // third column of options
  327.     printf("Number of Helix          :%d:\n", NOOFHELIX);
  328.     printf("Anticlock or clock helix :%d:\n", HELIXCLOCKWISE);
  329.     printf("Object face helix enable :%d:\n", ROTATETOFACE);
  330. }
  331.  
  332.  
  333.  
  334. /*
  335.     function - calculate all preset values for use in main engine
  336. */
  337. void CalculateSetValues()
  338. {
  339.     //calculate radian incrament per object
  340.     RadiansPerObject = (double) (360/RAD) / OBJECTSPERREV;
  341.  
  342.     //correct above value to clockwise (0)/anticlockwise (1) helix
  343.     if(HELIXCLOCKWISE == 0)
  344.         RadiansPerObject = RadiansPerObject;
  345.     else
  346.         RadiansPerObject = RadiansPerObject * (-1);
  347.  
  348.     // calculate incramented helix length for each sphere
  349.     LengthPerObject = (double) LENGTHPERREV / OBJECTSPERREV;
  350.  
  351.     // is the helix being made going down
  352.     if(HELIXLENGTH < 0)
  353.         LengthPerObject = LengthPerObject * (-1);
  354.  
  355.  
  356.     // calculate the minimum helix size
  357.     if(HELIXRADSTART == HELIXRADEND)
  358.     {  // start and end radius are the same, helix is a cylinder
  359.         HelixRadiusStart        = HELIXRADSTART;
  360.         HelixRadiusIncPerObject = 0;
  361.     }
  362.     else
  363.     {  // start and end radius are diferent, helix is a cone
  364.         HelixRadiusStart        = HELIXRADSTART;
  365.         HelixRadiusIncPerObject = (double) ((HELIXRADEND-HELIXRADSTART) / (HELIXLENGTH/LengthPerObject));
  366.     }
  367.  
  368.     // load up the starting object number in the helix
  369.     Objno = STARTOBJNO;
  370.  
  371.     // calculate the helix rotation offset for the helix in radians
  372.     HelixRotationY = (float) HELIXROTATEY / RAD;
  373.  
  374.     // tmp stuff for debugging
  375.     printf("RadiansPerObject         :%f:\n", RadiansPerObject);
  376.     printf("LengthPerObject          :%f:\n", LengthPerObject);
  377.     printf("HelixRadiusIncPerObject  :%f:\n", HelixRadiusIncPerObject);
  378.     printf("HelixRadiusStart         :%f:\n", HelixRadiusStart);
  379.     printf("HelixRotationY           :%f:\n", HelixRotationY);
  380. }
  381.  
  382.  
  383. /*
  384.     function - root of the calculation for the helix
  385. */
  386. void CalculateHelix()
  387. {
  388.     double tmp;
  389.  
  390.     // how many helix we have to do?
  391.     if(NOOFHELIX == 0)
  392.     {
  393.         tmp = 0;
  394.         MakeHelix( (double) 0*tmp );
  395.     }
  396.     else
  397.     if(NOOFHELIX == 1)
  398.     {
  399.         tmp = (double) (M_PI);
  400.         MakeHelix( (double) 0*tmp );
  401.         MakeHelix( (double) 1*tmp );
  402.     }
  403.     else
  404.     if(NOOFHELIX == 2)
  405.     {
  406.         tmp = (double) ((2*M_PI)/3);
  407.         MakeHelix( (double) 0*tmp );
  408.         MakeHelix( (double) 1*tmp );
  409.         MakeHelix( (double) 2*tmp );
  410.     }
  411.     else
  412.     if(NOOFHELIX == 3)
  413.     {
  414.         tmp = (double) ((2*M_PI)/4);
  415.         MakeHelix( (double) 0*tmp );
  416.         MakeHelix( (double) 1*tmp );
  417.         MakeHelix( (double) 2*tmp );
  418.         MakeHelix( (double) 3*tmp );
  419.     }
  420.     else
  421.     if(NOOFHELIX == 4)
  422.     {
  423.         tmp = (double) ((2*M_PI)/5);
  424.         MakeHelix( (double) 0*tmp );
  425.         MakeHelix( (double) 1*tmp );
  426.         MakeHelix( (double) 2*tmp );
  427.         MakeHelix( (double) 3*tmp );
  428.         MakeHelix( (double) 4*tmp );
  429.     }
  430.     else
  431.     if(NOOFHELIX == 5)
  432.     {
  433.         tmp = (double) ((2*M_PI)/6);
  434.         MakeHelix( (double) 0*tmp);
  435.         MakeHelix( (double) 1*tmp);
  436.         MakeHelix( (double) 2*tmp);
  437.         MakeHelix( (double) 3*tmp);
  438.         MakeHelix( (double) 4*tmp);
  439.         MakeHelix( (double) 5*tmp);
  440.     }
  441.  
  442.     // close down helix1.inc file
  443.     fclose(Helix);
  444.  
  445.     // say that we are finished
  446.     printf("\nYour column of spheres await!\n");
  447.     printf("\nHit a key to continue...\n");
  448.     getch();
  449. }
  450.  
  451.  
  452. /*
  453.     function to acutally produce a helix
  454. */
  455. void MakeHelix(double rotationcounter)
  456. {
  457.  
  458.     double x;    // x co-ord
  459.     double y;    // y co-ord
  460.     double z;    // z co-ord
  461.  
  462.     double xrot; // x rotation
  463.     double yrot; // y rotation
  464.     double zrot; // z rotation
  465.  
  466.     double lengthcounter;  // Helix length change accumulator counter
  467.     double radiuscounter;  // Helix radius change accumulator counter
  468.  
  469.     // add any user rotation offset to the rotation start value
  470.     rotationcounter = rotationcounter + HelixRotationY;
  471.  
  472.     // continue until helix length has been covered
  473.     for(lengthcounter = 0, radiuscounter = 0;
  474.          fabs(lengthcounter) < fabs(HELIXLENGTH);
  475.          lengthcounter   += LengthPerObject,
  476.          rotationcounter += RadiansPerObject,
  477.          radiuscounter   += HelixRadiusIncPerObject)
  478.     {
  479.         // update x co-ord
  480.         x    = CalcXcoord(rotationcounter, radiuscounter);
  481.  
  482.         // update y co-ord
  483.         y    = CalcYcoord(lengthcounter);
  484.  
  485.         // update z co-ord
  486.         z    = CalcZcoord(rotationcounter, radiuscounter);
  487.  
  488.         // update the x rotation value
  489.         xrot = CalcXrotation();
  490.  
  491.         // update the y rotation value
  492.         yrot = CalcYrotation(rotationcounter);
  493.         // update the z rotation value
  494.         zrot = CalcZrotation();
  495.  
  496.         // print current information to helixrod.inc
  497.         fprintf(Helix,"\n"); // You need this line first
  498.  
  499.         fprintf(Helix,"Object %05d: %d\n",Objno,OBJECTTYPE);
  500.  
  501.         fprintf(Helix,"Object %05d: 0 0 0\n",Objno);        // special vectors
  502.  
  503.         fprintf(Helix,"Object %05d: %.4f %.4f %.4f\n",Objno, (float) OBJECTSCALEX,  (float) OBJECTSCALEY,  (float) OBJECTSCALEZ);    // scale
  504.         fprintf(Helix,"Object %05d: %.4f %.4f %.4f\n",Objno, (float) xrot,          (float) yrot,          (float) zrot);                                    // rotate
  505.         fprintf(Helix,"Object %05d: %.4f %.4f %.4f\n",Objno, (float) x,             (float) y,             (float) z);                // translate
  506.  
  507.         fprintf(Helix,"Object %05d: 7\n",Objno);
  508.         fprintf(Helix,"Object %05d: Default\n",Objno);
  509.  
  510.         Objno = Objno + 1;
  511.  
  512.         // give the user a status report
  513.         printf("\rCurrent object being created:%.4d:.", Objno);
  514.  
  515.         if ((kbhit()) && getch()==27)
  516.         {
  517.             fclose(Helix);
  518.             remove("Helix.INC");
  519.             exit(0);
  520.         }
  521.     }
  522. }
  523.  
  524. // this is a list of what the above fprintf parameters do.
  525.  
  526. // object number, object type
  527.  
  528. // object number, special vectors (blob, torus vectors)
  529. // object number, x,y,z scale (reference by 1,1,1 object)
  530. // object number, x,y,z rotate object
  531. // object number, x,y,z translate object
  532.  
  533. // object number, colour
  534. // object number, texture
  535.  
  536. /*
  537.     functions - 3 of them
  538.                     calculate the X, Y and Z co-ordinate for the object in question
  539.     NOTE: the (-1)'s are there because of the co-ordinate description
  540.             system used in POVLAB (Y and Z co-ords only.
  541. */
  542. double CalcXcoord(double rotationcounter, double radiuscounter)
  543. {
  544.     return (((HelixRadiusStart + radiuscounter) * sin(rotationcounter)) +
  545.                  HELIXOFFSETX);
  546. }
  547.  
  548.  
  549. double CalcYcoord(double lengthcounter)
  550. {
  551.     return ( (lengthcounter + HELIXOFFSETY) * (-1));
  552. }
  553.  
  554.  
  555. double CalcZcoord(double rotationcounter, double radiuscounter)
  556. {
  557.     return ((((HelixRadiusStart + radiuscounter) * cos(rotationcounter)) +
  558.                  HELIXOFFSETZ) * (-1));
  559. }
  560.  
  561.  
  562.  
  563. /*
  564.     functions - 3 of them
  565.                     All caclulate an axis of rotation, Y is the only one
  566.                     that really does something.
  567. */
  568. double CalcXrotation()
  569. {
  570.     return OBJECTROTATEX;
  571. }
  572.  
  573.  
  574. double CalcYrotation(double rotationcounter)
  575. {
  576.     double a;
  577.  
  578.     if(ROTATETOFACE == 1)
  579.         a = (rotationcounter * RAD) + OBJECTROTATEY;
  580.     else
  581.         a = OBJECTROTATEY;
  582.  
  583.     // remove multiples of 360 degrees
  584.     while(a > 360)
  585.         a = a - 360;
  586.  
  587.     while(a < 0)
  588.         a = a + 360;
  589.  
  590.     return (a * (-1));
  591. }
  592.  
  593.  
  594. double CalcZrotation()
  595. {
  596.     return OBJECTROTATEZ;
  597. }
  598.  
  599. /* END OF FILE */